////////////////////////////////////////////////////
// Name:        stringtable.cpp
// Purpose:     Manages a table of strings, e.g. alternative translations
// Author:      Julian Smart
// Modified by:
// Created:     2008-02-05
// RCS-ID:      $Id$
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
////////////////////////////////////////////////////

#include "wx/wx.h"

#include "wx/valgen.h"
#include "wx/fileconf.h"

#include "datautils/stringtable.h"

/*
 * wxStringTable holds an arbitrary set of strings and associated
 * translations/alternatives.
 */

// Add a string
void wxStringTable::AddString(const wxString& name, const wxString& value)
{
    int idx = m_stringNames.Index(name);
    if (idx == -1)
    {
        m_stringNames.Add(name);
        m_stringValues.Add(value);
    }
    else
    {
        m_stringValues[idx] = value;
    }
}

// Remove a string
void wxStringTable::RemoveString(const wxString& name)
{
    int idx = m_stringNames.Index(name);
    if (idx != -1)
    {
        m_stringNames.RemoveAt(idx);
        m_stringValues.RemoveAt(idx);
    }
}

void wxStringTable::RemoveString(int idx)
{
    m_stringNames.RemoveAt(idx);
    m_stringValues.RemoveAt(idx);
}

// Find a string index
int wxStringTable::FindString(const wxString& name) const
{
    return m_stringNames.Index(name);
}

// Get the string for the given string, or the value of name if not found or empty
wxString wxStringTable::GetString(const wxString& name) const
{
    int idx = m_stringNames.Index(name);
    if (idx == -1)
        return name;
    else
    {
        if (m_stringValues[idx].IsEmpty())
            return name;
        else
            return m_stringValues[idx];
    }
}

// Get the string at the given index
wxString wxStringTable::GetString(size_t i) const
{
    if (m_stringValues[i].IsEmpty())
        return m_stringNames[i];
    else
        return m_stringValues[i];
}

// Get the string pointer at the given index
wxString* wxStringTable::GetStringPtr(size_t i) const
{
    return & m_stringValues[i];
}

// Get the string at the given index, without substituting the name for an empty string
wxString wxStringTable::GetStringRaw(size_t i) const
{
    return m_stringValues[i];
}

// Get the name at the given index
wxString wxStringTable::GetName(size_t i) const
{
    return m_stringNames[i];
}

// Set the name at the given index
void wxStringTable::SetName(size_t i, const wxString& name)
{
    m_stringNames[i] = name;
}

// Set the value at the given index
void wxStringTable::SetString(size_t i, const wxString& value)
{
    m_stringValues[i] = value;
}

// Set the value for the given name, adding if not found.
void wxStringTable::SetString(const wxString& name, const wxString& value)
{
    AddString(name, value);
}

// Just clear the values
void wxStringTable::ClearValues()
{
    size_t i;
    for (i = 0; i < GetCount(); i++)
    {
        m_stringValues[i] = wxEmptyString;
    }
}

// Load from file
bool wxStringTable::LoadFile(const wxString& filename)
{
    if (wxFileExists(filename))
    {
        ClearValues();
        wxFileConfig config(wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_LOCAL_FILE);

        config.Read(wxT("Table/TableName"), & m_tableName);

        config.SetPath(wxT("Strings"));

        int i = 0;
        while (true)
        {
            wxString key1(wxString::Format(wxT("String%d_Name"), i));
            wxString key2(wxString::Format(wxT("String%d_Value"), i));
            wxString name, value;
            if (config.Read(key1, & name))
            {
                config.Read(key2, & value);
                SetString(name, value);

                i ++;
            }
            else
                break;
        }

        return true;
    }

    return false;
}

// Save to file
bool wxStringTable::SaveFile(const wxString& filename)
{
    if (wxFileExists(filename))
        wxRemoveFile(filename);

    wxFileConfig config(wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_LOCAL_FILE);
    
    config.Write(wxT("Table/TableName"), m_tableName);
    
    config.SetPath(wxT("Strings"));
    
    size_t i;
    for (i = 0; i < GetCount(); i++)
    {
        wxString key1(wxString::Format(wxT("String%d_Name"), i));
        wxString key2(wxString::Format(wxT("String%d_Value"), i));
        wxString name = GetName(i);
        wxString value = GetStringRaw(i);
        config.Write(key1, name);
        config.Write(key2, value);
    }

    return true;
}

/*!
 * wxStringTablePanel type definition
 */

IMPLEMENT_DYNAMIC_CLASS( wxStringTablePanel, wxScrolledWindow )


/*!
 * wxStringTablePanel event table definition
 */

BEGIN_EVENT_TABLE( wxStringTablePanel, wxScrolledWindow )
END_EVENT_TABLE()


/*!
 * wxStringTablePanel constructors
 */

wxStringTablePanel::wxStringTablePanel()
{
    Init();
}

wxStringTablePanel::wxStringTablePanel( wxStringTable* table, wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
{
    Init();
    Create(table, parent, id, pos, size, style);
}


/*!
 * wxStringTablePanel creator
 */

bool wxStringTablePanel::Create( wxStringTable* table, wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
{
    m_table = table;

    wxScrolledWindow::Create( parent, id, pos, size, style );

    CreateControls();
    if (GetSizer())
    {
        GetSizer()->Fit(this);
    }
    return true;
}


/*!
 * wxStringTablePanel destructor
 */

wxStringTablePanel::~wxStringTablePanel()
{
}


/*!
 * Member initialisation
 */

void wxStringTablePanel::Init()
{
    m_table = NULL;
}


/*!
 * Control creation for wxStringTablePanel
 */

void wxStringTablePanel::CreateControls()
{    
#ifdef __WXMAC__
    SetWindowVariant(wxWINDOW_VARIANT_SMALL);
#endif

    RebuildTable();

    TransferDataToWindow();

    SetScrollbars(10, 10, 0, 0);
}

// Refresh table
void wxStringTablePanel::ShowTable()
{
    if (m_table)
    {
    }
}

// Rebuild and refresh table
void wxStringTablePanel::RebuildTable(wxStringTable* table)
{
    if (table)
        SetTable(table);
    else
        table = GetTable();

    // TODO: clear existing controls
    wxSizer* topSizer = GetSizer();
    if (!topSizer)
        topSizer = new wxBoxSizer(wxVERTICAL);
    SetSizer(topSizer);

    if (table)
    {
        size_t i;
        for (i = 0; i < table->GetCount(); i++)
        {
            wxString name = table->GetName(i);
            wxString* value = table->GetStringPtr(i);

            wxStaticText* staticText = new wxStaticText(this, wxID_STATIC, name);
            topSizer->Add(staticText, 0, wxTOP|wxRIGHT|wxLEFT, 5);

            wxTextCtrl* textCtrl = new wxTextCtrl(this, wxID_STATIC, wxEmptyString);
            topSizer->Add(textCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT|wxLEFT, 5);
            textCtrl->SetValidator(wxGenericValidator(value));
        }
    }
}

